<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>grid实现瀑布流</title>
  <style>
    body {
      margin: 0;
    }
    .masonry {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-gap: 0 20px;
      align-items: start;
    }
    .item {
      background: #f8f8fa;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-bottom: 10px;
    }
    @media (min-width: 1280px) and (max-width: 1920px) {
      .masonry {
        grid-template-columns: repeat(3, 1fr);
      }
    }
    @media (min-width: 768px) and (max-width: 1280px) {
      .masonry {
        grid-template-columns: repeat(2, 1fr);
      }
    }
    @media (max-width: 768px) {
      .masonry {
        grid-template-columns: repeat(1, 1fr);
      }
    }
  </style>
</head>
<body>
  <div class="masonry">
  </div>

  <script>
    const calcRows = () => {
      const con = document.querySelector('.masonry');
      const style = getComputedStyle(con);
      // 获取当前列数
      const cols = style.gridTemplateColumns.split(" ").length;
      const colHeights = Array(cols).fill(0);
      for(let i=0;i<cols;i++){
        let itemc = buildItemCon(i+1);
        con.appendChild(itemc);
        let item = getItem(i+1);
        itemc.appendChild(item);
        colHeights[i] = item.offsetHeight;
      }
      for(let i=cols;i<50;i++){
        let minColHeight = Math.min.apply(null, colHeights);
        let colIndex = colHeights.indexOf(minColHeight);
        let item = getItem(i+1);
        item.style.gridColumnStart = colIndex;
        con.children[colIndex].appendChild(item);
        colHeights[colIndex] += item.offsetHeight;
      }
    }

    window.addEventListener('resize', calcRows)
    window.addEventListener('load', calcRows)


    function buildItemCon(i){
      let item = document.createElement('div');
      item.className = 'itemc';
      return item;
    } 

    function getItem(i){
      let item = document.createElement('div');
      item.className = 'item';
      item.textContent = 'item' + i;
      item.style.height = `${Math.floor(Math.random() * 200) + 100}px`;
      return item;
    }
  </script>
</body>
</html>